import { Button, Input, InputNumber, Select, Space, Switch, Tree } from 'antd';
import React, { useEffect, useState } from 'react';
import {  DeleteOutlined, PlusOutlined } from '@ant-design/icons'
const FieldSchema = ({ refresh, schema, pSchema, left = 0, index }: any) => {
  const isLeaf = ['array', 'object'].includes(schema.type)
  // const ChildrenField = () => {
  //   if (isLeaf) {
  //     if (!Array.isArray(schema.children)) {
  //       schema.children = []
  //     }
  //     return schema.children.map((item, index) => <FieldSchema pSchema={schema} index={index} refresh={refresh} left={left + 10} key={item.id} schema={item} />)
  //   }
  //   return null
  // }
  const TypeNode = {
    "string": <Input value={schema.value} onChange={e => {
      schema.value = e.target.value
      refresh()
    }} />,
    "boolean": <Switch
      checked={schema.value}
      onChange={e => {
        schema.value = e
        refresh()
      }} />,
    "number": <InputNumber
      value={schema.value}
      onChange={e => {
        schema.value = e
        refresh()
      }}
    />,
    "raw": <Input
    value={schema.value}
    onChange={e => {
      schema.value = e.target.value
      refresh()
    }}
  />,
  }
  return <div >
    <div style={{ marginLeft: left, marginBottom: 10 }}>
      <Space>
        {
          pSchema?.type == 'array' ? <Input disabled value={index + 1} /> : <Input
            onChange={e => {
              schema.key = e.target.value;
              refresh()
            }}
            value={schema.key} />
        }

        <Select
          onChange={e => {
            schema.type = e
            if (!Array.isArray(schema.children)) {
              schema.children = []
            }
            refresh()
          }}
          style={{ width: 100 }} value={schema.type} options={[
            { label: 'Array', value: 'array' },
            { label: 'Object', value: 'object' },
            { label: 'Number', value: 'number' },
            { label: 'String', value: 'string' },
            { label: 'Boolean', value: 'boolean' },
            { label: 'Raw', value: 'raw' },
          ]} />
        {TypeNode[schema.type]}
        {/* {
          isLeaf ? null :  <Input 
          onChange={e => {
            schema.value = e.target.value;
            refresh()
          }}

          value={schema.value} />
        } */}

        {
          isLeaf ? <Button
            size='small'
            // shape='circle'
            icon={<PlusOutlined />}
            onClick={() => {
              if (!schema.children) {
                schema.children = []
              }
              schema.children.push({
                key: `Field${Math.ceil(Math.random() * 100000)}`,
                id: String(Math.random()),
                value: `Value`,
                type: 'string'
              })
              refresh()
            }}></Button> : null
        }

        <Button
          size='small'
          // shape='circle'
          icon={<DeleteOutlined />} onClick={() => {
            const index = pSchema.children.findIndex(v => v.id === schema.id)
            pSchema.children.splice(index, 1)
            refresh()
          }}></Button>
      </Space>

    </div>
    {schema.children?.map((item, index) => <FieldSchema pSchema={schema} index={index} refresh={refresh} left={left + 15} key={item.id} schema={item} />)}
    {/* <ChildrenField /> */}
  </div>
}
const JsonEditor = ({ onChange,schema:_schema }: any) => {
  const [schema, setSchema] = useState<any[]>([])
  const refresh = () => {
    onChange && onChange(schema)
    setSchema([...schema])
  }
  useEffect(()=>{
      if(_schema){
        setSchema([..._schema])
      }
  },[_schema])
  return (<div>
    {schema.map(item => {
      return <FieldSchema
        pSchema={{
          children: schema
        }} refresh={refresh} key={item.id} schema={item} />
    })}
    <Button
      icon={<PlusOutlined />}
      onClick={() => {
        schema.push({
          id: String(Math.random()),
          key: `Node${Math.ceil(Math.random() * 100000)}`,
          value: 'Value',
          children: [],
          type: 'string'
        })
        refresh()
      }}>添加</Button>
  </div>
  )
}
JsonEditor.toJSON = (schema, isArray = false) => {
  const result: any = isArray ? [] : {};

  schema.forEach(item => {
    const value = item.value;
    const children = item.children || [];
    const type = item.type;

    if (type === "array") {
      if (isArray) {
        result.push(JsonEditor.toJSON(children, true))
      } else {
        result[item.key] = JsonEditor.toJSON(children, true)
      }
      // Process array type nodes

    } else if (type === "object") {
      if (isArray) {
        result.push(JsonEditor.toJSON(children))
      } else {
        result[item.key] = JsonEditor.toJSON(children)
      }
    } else if (type === "string") {
      if (isArray) {
        result.push(value)
      } else {
        result[item.key] = value
      }
    } else if (type === "number") {
      if (isArray) {
        result.push(+value)
      } else {
        result[item.key] = +value
      }
    } else if (type === "boolean") {

      if (isArray) {
        result.push(!!value)
      } else {
        result[item.key] = !!value
      }
    }
  });

  return result;
}


JsonEditor.toSchema = (json: any) => {
  if(!json){
    return []
  }
  const result: any[] = [];
  for (let key in json) {
    const item = json[key]
    let type = Array.isArray(item) ? 'array' : typeof item;
    let value = typeof item ==='object'?undefined: item
    let children: any[] = [];
    if (['object'].includes(type)) {
      children = JsonEditor.toSchema(item)
    }
    if ('array' === type) {
      children = item.map(v => {
        if (v === 'array') {
          return JsonEditor.toSchema(item)
        }
        if (v === 'object') {
          return JsonEditor.toSchema(item)
        }
        return v
      })
      
    }
    result.push({
      id: Math.random(),
      key,
      value,
      children,
      type
    })
  }
  return result
}

export default JsonEditor